package org.douxiaoban.client.api;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.douxiaoban.client.util.DouUtils;
import org.douxiaoban.data.DouGroupOneTopicData;
import org.douxiaoban.data.DouGroupOneTopicData.DouReplyItemData;
import org.douxiaoban.data.DouGroupTopicData;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * 获取豆瓣小组数据
 * 
 * @author 6a209 8:59:49 PM Apr 25, 2012
 */
public class DouGroupApi {

	// 小组api-------------------------------------------------------------

	/* 我的最新的话题 */
	private static final String NEWEST_TOPIC = "http://www.douban.com/group/";
	/* 我的话题 */
	public static final String MY_TOPIC = "http://www.douban.com/group/my_topics";
	/* 我回复的话题 */
	public static final String MY_REPLE_TOPIC = "http://www.douban.com/group/my_replied_topics";
//	/* 我参加的小组 */
//	private static final String MY_GROUP = "http://www.douban.com/group/mine";
	/* 热门小组推荐, %s 为要替代的关键字 */
	private static final String HOT_GROUP = "http://www.douban.com/j/explore/group/tag/%s/?start=0&limit=30";

	/* 小组详情, %s 为要替代的小组id */
	private static final String GROUP_DETAIL = "http://www.douban.com/group/%s/";
	/* 话题详情, %s 为要替代的话题id */
	private static final String TOPIC_DETAIL = "http://www.douban.com/group/topic/%s/";

	/* 加入某个小组 */
	// private static final String

	/* 退出某个小组 */

	/* 回应某个小组 */

	/* 回应某个人 */

	// !!小组api－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－

	
	
	// 抓数据的正则－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
	
	//的小组改版后的 最新－－－
	/*匹配小组信息 （小组头像）（小组链接） （小组名）*/
	private static final String GROUP_NEWEST_INFO_RE = "img\\ssrc=\"(.*?)\".*?href=\"(.*?)\">(.*?)<";
	/*匹配一个小组，及它的最新列表*/
	private static final String GROUP_NEWEST_ITEM_RE = "<li class=\"tl-item\">.*?</li>";
	/*匹配小组里的一个话题*/
	private static final String GROUP_NEWEST_TOPIC_ITEM_RE = "<div class=\"group-item\">.*?</div>";
	/*匹配一个一个话题(话题链接）(话题标题） (话题发表时间）*/
	private static final String GROUP_NEWEST_TOPIC_ITEM_INFO_RE = "href=\"(.*?)\">(.*?)<.*?timestamp\">(.*?)<";
	/**/
	//!!-- 改版后 最新
	
	

	/* 抓取topic 列表 的正则 */
	private static final String ITEM_RE = "<tr class=\"pl\">.*?</tr>";

	/*
	 * 分析topic 里面的每项内容,
	 * 
	 * 1,--title link; 2--title content; 3--group link; 4-- group name;
	 * 5,--reply count; 6--time;
	 * the tiem
	 */

	private static final String TOPIC_INFO_RE = "href=\"([^\"]*?)\">([^<]*?)<.*href=\"([^\"]*?)\">([^<]*?)<.*?right\">(\\d*)<.*?(\\d[^<]*?)<";
	private static final String ITEM_GROUP_NAME_RE = "<td.*?<a href=\"(.*?)\">(.*?)<a";
	/* 用于取作者名，和评论次数 和时间*/
	private static final String ITEM_AUTHO_COUNT_TIME_RE = 
		"<td>(.*?)</td>.*?<td.*?>(.*?)</td>.*?(\\d{2}-\\d{2}\\s\\d{2}:\\d{2})";
	/* xx-xx yy:yy 格式 */
//	private static final String ITEM_TIME_RE = "\\d{2}-\\d{2}\\s\\d{2}:\\d{2}";

	// !! 正则－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－

	private Context mCtx;
	private static DouGroupApi mApi;
	
	private DouGroupApi(Context ctx) {
		mCtx = ctx;
	}
	
	public static DouGroupApi instance(Context ctx){
		if(null == mApi){
			mApi = new DouGroupApi(ctx);
		}
		return mApi;
	}

	public ArrayList<DouGroupTopicData> getNewestTopic() throws Exception{
		return paresNewestTopic(httpGet(NEWEST_TOPIC, null));
	}
	
	private ArrayList<DouGroupTopicData> paresNewestTopic(String content){
		if(cookieIsTimeOut(content)){
			return null;
		}
		ArrayList<DouGroupTopicData> arrayTopic = new ArrayList<DouGroupTopicData>();
		DouGroupTopicData groupData = null;
		DouGroupTopicData topicData = null;
		Pattern pattern = Pattern.compile(GROUP_NEWEST_ITEM_RE);
		Matcher matcher = pattern.matcher(content);
		while(matcher.find()){
			String strItem = matcher.group(0);
			Pattern patternGroupInfo = Pattern.compile(GROUP_NEWEST_INFO_RE);
			Matcher matcherGroupInfo = patternGroupInfo.matcher(strItem);
			if(matcherGroupInfo.find()){
				//小组信息
				groupData = new DouGroupTopicData();
				groupData.mGroupIcon = matcherGroupInfo.group(1);
				groupData.mGroupLink = matcherGroupInfo.group(2);
				groupData.mGroupName = matcherGroupInfo.group(3);
				arrayTopic.add(groupData);
			}
			Pattern patternTopicItem = Pattern.compile(GROUP_NEWEST_TOPIC_ITEM_RE);
			Matcher matcherTopicItem = patternTopicItem.matcher(strItem);
			while(matcherTopicItem.find()){
				//最新话题
				String topicInfo = matcherTopicItem.group(0);
				Pattern patternTopicInfo = Pattern.compile(GROUP_NEWEST_TOPIC_ITEM_INFO_RE);
				Matcher matcherTopicInfo = patternTopicInfo.matcher(topicInfo);
				
				if(matcherTopicInfo.find()){
					String strTopicInfo = matcherTopicInfo.group(0);
					topicData = new DouGroupTopicData();
					topicData.mTopicLink = matcherTopicInfo.group(1);
					topicData.mTitile= matcherTopicInfo.group(2);
					topicData.mLastReplyTime = matcherTopicInfo.group(3);
					int startIndex = strTopicInfo.indexOf("reply");
					//有回复和木有回复 有差别- 
					if(-1 != startIndex){
						int end = strTopicInfo.indexOf("<", startIndex);
						topicData.mReplyCount = strTopicInfo.substring(startIndex + 7, end);
					}else{
						topicData.mReplyCount = "0回应";
					}
					if(null != groupData){
						topicData.mGroupLink = groupData.mGroupLink;
						topicData.mGroupName = groupData.mGroupName;
					}
					arrayTopic.add(topicData);
				}
			}
		}
		return arrayTopic;
	}
	
	/**
	 * 判断cookie 是否过期, 
	 * 判断当前的标题是我的小组还是
	 * @param content 
	 * @return
	 */
	private static final String TITTLE_RE = "<title>(.*?)</title>";
	public boolean cookieIsTimeOut(String content){
		Pattern patter = Pattern.compile(TITTLE_RE);
		Matcher matcher = patter.matcher(content);
		if(matcher.find()){
			String title = matcher.group(1);
			title = title.trim();
			if(title.equals("豆瓣小组")){
				return false;
			}
		}
		return false;
		
	}
	
	public ArrayList<DouGroupTopicData> getDouGroupTopicData(String url, int start){
		BasicHttpParams params = new BasicHttpParams();
		params.setParameter("start", start);
		String httpContent = null;
		ArrayList<DouGroupTopicData> arrayTopic = null;
		try {
			httpContent = httpGet(url, params);
			arrayTopic = paresTopicList(httpContent);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return arrayTopic;
	}

	//听说会自动释放链接－！
	private String httpGet(String url, HttpParams params) throws ClientProtocolException,
			IOException {
		DefaultHttpClient httpClient = new DefaultHttpClient();
		httpClient.setCookieStore(DouUtils
				.getInstance(mCtx.getApplicationContext()).getCookieUtil()
				.getLoginCookieStore());
		HttpGet httpGet = new HttpGet(url);
		if(null != params){
			httpGet.setParams(params);
		}
		HttpResponse response = httpClient.execute(httpGet);
		InputStreamReader is = new InputStreamReader(response.getEntity()
				.getContent(), "utf-8");
		BufferedReader bufferedReader = new BufferedReader(is);
		StringBuffer temp = new StringBuffer();
		String line = bufferedReader.readLine();
		while (line != null) {
			temp.append(line);
			line = bufferedReader.readLine();
		}
//		httpGet.
		return temp.toString();
	}
	
	
	//随机 User-Agent 
	String []user_agents = {
	               "Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11",
	               "Opera/9.25 (Windows NT 5.1; U; en)",
	               "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
	               "Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)",
	               "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12",
	               "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
	};
	
	private String getUserAgents(){
		Random random = new Random();
		int pos = random.nextInt();
		pos = Math.abs(pos % 6);
		return user_agents[pos];
	}
	
	private String httpPost(String url, HttpParams params, List<NameValuePair> nameValuePairs) throws Exception{
		DefaultHttpClient httpClient = new DefaultHttpClient();
		httpClient.setCookieStore(
			DouUtils.getInstance(mCtx.getApplicationContext()).getCookieUtil().getLoginCookieStore());
		HttpPost httpPost = new HttpPost(url);
		httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
		if(null != params){
			httpPost.setParams(params);
		}
		HttpResponse response = httpClient.execute(httpPost);
		InputStreamReader is = new InputStreamReader(response.getEntity()
				.getContent(), "utf-8");
		BufferedReader bufferedReader = new BufferedReader(is);
		StringBuffer temp = new StringBuffer();
		String line = bufferedReader.readLine();
		while (line != null) {
			temp.append(line);
			line = bufferedReader.readLine();
		}
		Log.v("the post 000000----------", temp.toString());
//		if(200 == response.getStatusLine().getStatusCode()){
//			return true;
//		}else{
//			return false;
//		}
		return temp.toString();
	}
	
	private ArrayList<DouGroupTopicData> paresTopicList(String content) {
		ArrayList<DouGroupTopicData> arrayTopic = new ArrayList<DouGroupTopicData>();
		Pattern pattern = Pattern.compile(ITEM_RE);
		Matcher matcher = pattern.matcher(content);
		while(matcher.find()){
			DouGroupTopicData topic = new DouGroupTopicData();
			//匹配每个item中的一行
			String strItem = matcher.group(0);
			
			//标题
			Pattern patternTopicInfo = Pattern.compile(TOPIC_INFO_RE);
			Matcher matcherTopicInfo = patternTopicInfo.matcher(strItem);
			if(matcherTopicInfo.find()){
				topic.mTopicLink = matcherTopicInfo.group(1);
				topic.mTitile = matcherTopicInfo.group(2);
				topic.mGroupLink = matcherTopicInfo.group(3);
				topic.mGroupName = matcherTopicInfo.group(4);
				topic.mReplyCount = matcherTopicInfo.group(5);
				if(null == topic.mReplyCount &&  0 == topic.mReplyCount.length()){
					topic.mReplyCount = "0";
				}
				topic.mLastReplyTime = matcherTopicInfo.group(6);
			}
			arrayTopic.add(topic);
		}
		return arrayTopic;
	}
	
	
	/**
	 * 单个话题详情 -- 包括回复
	 * @param url  
	 * @param start
	 * @return
	 */
	public DouGroupOneTopicData getOneTopicData(String url, int start){
		BasicHttpParams params = new BasicHttpParams();
		params.setParameter("start", start);
		String httpContent = null;
		try {
			httpContent = httpGet(url, params);
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		DouGroupOneTopicData oneTopic = parseOneTopic(httpContent);
		return oneTopic;
	}
	
	/**
	 * 获取单条话题的更多评论-
	 * @param url
	 * @param start
	 * @return
	 */
	public ArrayList<DouReplyItemData> getMoreReplys(String url, int start){
		DouGroupOneTopicData data = getOneTopicData(url, start);
		return data.mReplys;
	}
	
	/*item 拿出整个数据*/
	private static final String ONE_TOPIC_ITEM_RE = "id=\"content\"(.*?)topic-opt clearfix";
	private static final String ONE_TOPIC_INFO_RE = 
		"src=\"([^\"]*?)\".*(\\d{4}-\\d{2}-\\d{2}\\s?\\d{2}:\\d{2}:\\d{2}).*?<a.*?>(.*?)</a>(.*?)</span>.*topic-content\">(.*?)</div>";
	
	/**
	 * 解析单个话题- 包括回复
	 * @param contentk
	 */
	private DouGroupOneTopicData parseOneTopic(String content){
		DouGroupOneTopicData oneTopicData = new DouGroupOneTopicData();
		Pattern oneTopicPattern = Pattern.compile(ONE_TOPIC_ITEM_RE);
		Matcher oneTopicMatcher = oneTopicPattern.matcher(content);
		if(oneTopicMatcher.find()){
			String item = oneTopicMatcher.group(1);
			oneTopicData.mTitle = getTopicTitle(item);
			Pattern oneTopicInfoPattern = Pattern.compile(ONE_TOPIC_INFO_RE);
			Matcher oneTopicInfoMatcher = oneTopicInfoPattern.matcher(item);
			if(oneTopicInfoMatcher.find()){
				oneTopicData.mCurTopicInfo.mAvatarLink = oneTopicInfoMatcher.group(1);
				oneTopicData.mCurTopicInfo.mTime = oneTopicInfoMatcher.group(2);
				oneTopicData.mCurTopicInfo.mName = oneTopicInfoMatcher.group(3);
				oneTopicData.mCurTopicInfo.mSignature = oneTopicInfoMatcher.group(4);
				oneTopicData.mCurTopicInfo.mContent = oneTopicInfoMatcher.group(5);
			}
		}
		oneTopicData.mReplys = parseTopicReplys(content);
		oneTopicData.mReplyPageCount = parsePage(content);
		return oneTopicData;
	}
	
	private String getTopicTitle(String content){
		String isToLongFlag = "<strong>标题: </strong>";
		String title = "";
		int start;
		int end;
		int index = content.indexOf(isToLongFlag);
		if(-1 == index){
			//标题未过长
			String h1Start = "<h1>";
			String h1End = "</h1>";
			start = content.indexOf(h1Start);
			end = content.indexOf(h1End);
			title = content.substring(start + h1Start.length(), end);
		}else{
			end = content.indexOf("</td>", index);
			title = content.substring(index + isToLongFlag.length(), end);
		}
		return title;
	}
	
	private static final String ONE_TOPIC_REPLY_ITEM_RE = "<li\\sclass=\"[\\w,\\d]+\"\\sid=\"[\\d,\\w]+\".*?</li";
	private static final String ONE_TOPIC_REPLY_INFO_RE = 
			"src=\"([^\"]*?)\".*(\\d{4}-\\d{2}-\\d{2}\\s?\\d{2}:\\d{2}:\\d{2}).*?<a.*?>(.*?)</a>(.*?)</h.*<p>(.*?)</p>.*href=\"(.*?)\"";
	private ArrayList<DouReplyItemData> parseTopicReplys(String content){
		ArrayList<DouReplyItemData> listData = new ArrayList<DouReplyItemData>();
		Pattern patternItem = Pattern.compile(ONE_TOPIC_REPLY_ITEM_RE);
		Matcher matcherItem = patternItem.matcher(content);
		while(matcherItem.find()){
			String itemContent = matcherItem.group();
			Pattern patternInfo = Pattern.compile(ONE_TOPIC_REPLY_INFO_RE);
			Matcher matcherInfo = patternInfo.matcher(itemContent);
			if(matcherInfo.find()){
				DouReplyItemData itemData = new DouReplyItemData();
				itemData.mAvatarLink = matcherInfo.group(1);
				itemData.mTime = matcherInfo.group(2);
				itemData.mName = matcherInfo.group(3);
				itemData.mSignature = matcherInfo.group(4);
				itemData.mContent = matcherInfo.group(5);
				itemData.mReplyLink = matcherInfo.group(6);
				getReplyQuote(itemContent, itemData);
				listData.add(itemData);
			}
		}
		
		return listData;
	}
	
	
	/**
	 * 这个真是太难用了-~~~~ 正则无敌
	 * @param content
	 * @param item
	 */
	private void getReplyQuote(String content, DouReplyItemData item){
		String startStr = "<span class=\"short\">";
		String endStr = "</";
		String repNameStartStr = "pubdate\"><a href=\"";
		int startIndex = content.indexOf(startStr);
		if(-1 != startIndex){
			int endIndex = content.indexOf(endStr, startIndex);
			String repContent = content.substring(startIndex + startStr.length(), endIndex);
			if(-1 != content.indexOf("expanded", endIndex)){
				repContent +="...";
			}
			item.mReplyQuote = repContent;
			int repNameStart = content.indexOf(repNameStartStr);
			if(-1 != repNameStart){
				repNameStart += repNameStartStr.length();
				int repNameEnd = content.indexOf("\"", repNameStart);
				item.mReplyNameLink = content.substring(repNameStart, repNameEnd);
				//">
				repNameStart = repNameEnd + 2;
				repNameEnd = content.indexOf("<", repNameStart);
				item.mReplyName = content.substring(repNameStart, repNameEnd);
				item.mReplyQuote += "<font color=\"#2F5487\">" + "        " + item.mReplyName + "</font>"; 
			}
		}else{
			item.mReplyQuote = null;
		}
	}
	
	// !--
	
	/**
	 * 解析评论有多少分页 
	 * @param content
	 * @return 返回评论的分页
	 */
	
	private static final String PAGE_COUNT_RE = "href=\"[^\"]+\"\\s>(\\d+)</a>\\s+<span\\s?class=\"next\">";
	private int parsePage(String content){
		Pattern pattern = Pattern.compile(PAGE_COUNT_RE);
		Matcher matcher = pattern.matcher(content);
		if(matcher.find()){
			int pageCount = Integer.parseInt(matcher.group(1));
			return pageCount;
		}
		return 0;
	}
	
	
	/**
	 * 回复评论
	 * @param url 回复的url地址
	 * @param nameValuePairs 参数列表
	 * @return 成功返回true
	 */
	public DouGroupOneTopicData replyTopic(String url, List<NameValuePair> nameValuePairs){
		try {
			BasicHttpParams params = new BasicHttpParams();
			List<Header> headers = new ArrayList<Header>();
			headers.add(new BasicHeader("User-Agent", getUserAgents()));
			headers.add(new BasicHeader("Referer", url));
			url = url + "add_comment#last";
			params.setParameter("http.default-headers", headers);
			String content = httpPost(url, params, nameValuePairs);
			DouGroupOneTopicData data = parseOneTopic(content);
			return data;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}